package com.stek.main;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
import android.provider.Settings.System;
import android.support.v4.content.IntentCompat;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageButton;
import android.widget.ViewFlipper;

import com.stek.R;
import com.stek.app.AppActivity;
import com.stek.camera.MirrorActivity;
import com.stek.camera.TorchActivity;
import com.stek.db.DBHelper;
import com.stek.model.AppInfo;
import com.stek.model.FloatInfo;
import com.stek.spec.SpecsActivity;
import com.stek.utils.AppUtils;
import com.stek.utils.CONFIG;
import com.stek.utils.Utils;
import com.stericson.RootTools.RootTools;

public class MainService extends Service implements OnClickListener {
	// ==============================================================
	private WindowManager mWindowManager;
	private LayoutParams mFloatIconParams;
	private LayoutParams mFloatViewParams;
	private ImageButton mFloatIcon;
	private ViewFlipper mFloatView;
	private int mFlagParams;
	private float mX = 0;
	private float mY = 0;
	private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
				int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
						WifiManager.WIFI_STATE_DISABLED);
				View wifi = mFloatView
						.findViewWithTag(getString(R.string.tag_wifi));
				if (null != wifi) {
					wifi.setSelected(state == WifiManager.WIFI_STATE_ENABLED);
				}

			} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
				int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
						BluetoothAdapter.STATE_OFF);
				View bluetooth = mFloatView
						.findViewWithTag(getString(R.string.tag_bluetooth));
				if (null != bluetooth) {
					bluetooth.setSelected(state == BluetoothAdapter.STATE_ON);
				}
			} else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
				NetworkInfo netInfo = intent
						.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
				if (netInfo != null
						&& netInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
					View data = mFloatView
							.findViewWithTag(getString(R.string.tag_data));
					if (null != data) {
						data.setSelected(netInfo.isConnected());
					}

				}

			} else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
				ImageButton imgSound = (ImageButton) mFloatView
						.findViewWithTag(getString(R.string.tag_sound));
				if (null == imgSound) {
					return;
				}
				int state = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE,
						AudioManager.RINGER_MODE_NORMAL);
				switch (state) {
				case AudioManager.RINGER_MODE_NORMAL:
					imgSound.setImageResource(R.drawable.btn_volume_on);
					break;
				case AudioManager.RINGER_MODE_SILENT:
					imgSound.setImageResource(R.drawable.btn_volume_mute);
					break;
				case AudioManager.RINGER_MODE_VIBRATE:
					imgSound.setImageResource(R.drawable.btn_vibrate);
					break;
				default:
					break;
				}
			} else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
				boolean state = intent.getBooleanExtra("state", false);
				View airplane = mFloatView
						.findViewWithTag(getString(R.string.tag_airplane));
				if (null != airplane) {
					airplane.setSelected(state);
				}

			} else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
				View rotation = mFloatView
						.findViewWithTag(getString(R.string.tag_rotate));
				if (null != rotation) {
					rotation.setSelected(Utils.Rotation
							.isAutoOrientationEnabled(getApplicationContext()));
				}

			} else if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(action)) {
				View gps = mFloatView
						.findViewWithTag(getString(R.string.tag_gps));
				if (null != gps) {
					gps.setSelected(Utils.GPS
							.isGpsEnabled(getApplicationContext()));
				}
			} else if (CONFIG.BROADCAST.ACTION_FLOAT_ICON_RESOURCE_CHANGED
					.equals(action)) {
				mFloatIcon.setImageResource(CONFIG.FLOAT_ICON
						.getFloatIcon(getApplicationContext()));

			} else if (CONFIG.BROADCAST.ACTION_FAVORITE_APP_CHANGED
					.equals(action)) {
				loadFav(mFloatView);
			} else if (CONFIG.BROADCAST.ACTION_MAIN_PANEL_CHANGED
					.equals(action)) {
				loadMain(mFloatView);
			} else if (CONFIG.BROADCAST.ACTION_SUB_PANEL_CHANGED.equals(action)) {
				loadSub(mFloatView);
			} else if (CONFIG.BROADCAST.ACTION_SHOW_ICON_ON_LOCK_SETTINFS
					.equals(action)) {
				boolean isShown = intent.getBooleanExtra(
						CONFIG.BROADCAST.EXTRA_FLOATING_ICON_SETTINFS, true);
				if (isShown) {
					startForeGroundService();
				} else {
					stopForeGroundService();
				}
			}
		}
	};

	private ContentObserver mObserver = new ContentObserver(new Handler()) {
		public void onChange(boolean selfChange, android.net.Uri uri) {
			if (System.getUriFor(System.ACCELEROMETER_ROTATION).equals(uri)) {
				int state = System.getInt(getContentResolver(),
						System.ACCELEROMETER_ROTATION, 0);
				View rotation = mFloatView
						.findViewWithTag(getString(R.string.tag_rotate));
				if (null != rotation) {
					rotation.setSelected(state == 1);
				}

			}
		};
	};

	// ==============================================================
	@Override
	public IBinder onBind(Intent intent) {
		// TODO: Return the communication channel to the service.
		throw new UnsupportedOperationException("Not yet implemented");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return START_STICKY;
	}

	@Override
	public void onCreate() {
		initWindow();
		loadMain(mFloatView);
		loadSub(mFloatView);
		loadFav(mFloatView);
		IntentFilter filter = new IntentFilter();
		filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
		filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
		filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
		filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
		filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
		filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
		filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
		filter.addAction(CONFIG.BROADCAST.ACTION_FLOAT_ICON_RESOURCE_CHANGED);
		filter.addAction(CONFIG.BROADCAST.ACTION_FAVORITE_APP_CHANGED);
		filter.addAction(CONFIG.BROADCAST.ACTION_MAIN_PANEL_CHANGED);
		filter.addAction(CONFIG.BROADCAST.ACTION_SUB_PANEL_CHANGED);
		filter.addAction(CONFIG.BROADCAST.ACTION_SHOW_ICON_ON_LOCK_SETTINFS);
		registerReceiver(mBroadcastReceiver, filter);
		getContentResolver().registerContentObserver(
				System.getUriFor(System.ACCELEROMETER_ROTATION), true,
				mObserver);
		if (CONFIG.FLOAT_ICON.isShowFloatIcon(getApplicationContext())) {
			startForeGroundService();
		}
		init();
		super.onCreate();
	}

	private void init() {
		View view = null;
		if ((view = mFloatView
				.findViewWithTag(getString(R.string.tag_airplane))) != null) {
			view.setSelected(Utils.Airplane
					.isAirPlaneModeEnable(getApplicationContext()));
		}

	}

	@Override
	public void onDestroy() {
		unregisterReceiver(mBroadcastReceiver);
		getContentResolver().unregisterContentObserver(mObserver);
		super.onDestroy();
	}

	private void startForeGroundService() {

		android.support.v4.app.NotificationCompat.Builder builder = new android.support.v4.app.NotificationCompat.Builder(
				getApplicationContext());
		builder.setContentText(getString(R.string.one_touch_desc));
		builder.setContentTitle(getString(R.string.app_name));
		builder.setAutoCancel(false);
		builder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(
				this, MainActivity.class)
				.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
						| IntentCompat.FLAG_ACTIVITY_CLEAR_TASK), 0));
		builder.setSmallIcon(CONFIG.FLOAT_ICON.getFloatIcon(getApplicationContext()));
		Notification notif = builder.build();
		startForeground(8001, notif);

	}

	private void stopForeGroundService() {
		stopForeground(true);

	}

	private void initWindow() {
		mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		mFlagParams = LayoutParams.FLAG_LAYOUT_IN_SCREEN
				| LayoutParams.FLAG_NOT_FOCUSABLE
				| LayoutParams.FLAG_NOT_TOUCH_MODAL
				| LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
		mFloatIconParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT, 0, 0,
				LayoutParams.TYPE_SYSTEM_ERROR, mFlagParams,
				PixelFormat.TRANSLUCENT);
		mFloatViewParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT, 0, 0,
				LayoutParams.TYPE_SYSTEM_ERROR, mFlagParams,
				PixelFormat.TRANSLUCENT);
		mFloatViewParams.gravity = Gravity.CENTER;
		mFloatIcon = (ImageButton) LayoutInflater.from(getApplicationContext())
				.inflate(R.layout.view_float_icon, null);
		mFloatIcon.setImageResource(CONFIG.FLOAT_ICON
				.getFloatIcon(getApplicationContext()));
		mFloatView = (ViewFlipper) LayoutInflater.from(getApplicationContext())
				.inflate(R.layout.view_float_view_pager, null);
		mWindowManager.addView(mFloatIcon, mFloatIconParams);
		mWindowManager.addView(mFloatView, mFloatViewParams);
		mFloatView.setVisibility(View.GONE);
		mFloatIcon.setOnClickListener(this);
		mFloatIcon.setOnTouchListener(mTouchFloatIconListener);
		mFloatView.setOnTouchListener(mTouchFloatViewListener);

	}

	private void loadMain(View rootView) {
		DBHelper dbHelper = DBHelper.getInstance(this);
		for (int i = 0; i < 9; i++) {
			int id = getResources().getIdentifier("img" + i, "id",
					this.getPackageName());
			ImageButton view = (ImageButton) rootView.findViewById(id);
			FloatInfo info = dbHelper.findMain(this, i);
			if (info != null) {
				view.setTag(info.tag);
				view.setImageResource(info.resource);
				view.setOnClickListener(this);
				view.setVisibility(View.VISIBLE);
			} else {
				view.setVisibility(View.GONE);
			}
		}

	}

	private void loadSub(View rootView) {
		DBHelper dbHelper = DBHelper.getInstance(this);
		for (int i = 0; i < 9; i++) {
			int id = getResources().getIdentifier("imgsub" + i, "id",
					this.getPackageName());
			ImageButton view = (ImageButton) rootView.findViewById(id);
			FloatInfo info = dbHelper.findSettings(this, i);
			if (info != null) {

				view.setTag(info.tag);
				view.setImageResource(info.resource);
				view.setOnClickListener(this);
				view.setVisibility(View.VISIBLE);
			} else {
				view.setVisibility(View.GONE);
			}
		}

	}

	private void loadFav(View rootView) {
		for (int i = 0; i < 9; i++) {
			final AppInfo info = DBHelper.getInstance(this).findFavorite(this,
					i);
			int id = getResources().getIdentifier("img_favorite" + i, "id",
					this.getPackageName());
			ImageButton fav = (ImageButton) rootView.findViewById(id);
			if (null == info) {
				fav.setImageResource(R.drawable.btn_add);
			} else {
				Drawable icon = AppUtils.getApplicationIcon(this, info.pgk);
				if (null == icon) {
					DBHelper.getInstance(this).deleteFavorite(
							getApplicationContext(), i);
				} else {
					fav.setImageDrawable(icon);
				}
			}
			fav.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					showView(mFloatIcon);
					if (null != info) {
						AppUtils.launchApp(getApplicationContext(), info.pgk);
					} else {
						addFav(v);
					}

				}

			});
		}
		//
	}

	private void addFav(View v) {
		String tag = (String) v.getTag();
		int position = Integer.parseInt(tag.replace(
				getString(R.string.tag_favorite), ""));
		Bundle bundle = new Bundle();
		bundle.putBoolean(AppActivity.EXTRA_PICK_APP, true);
		bundle.putInt(AppActivity.EXTRA_APP_POSITION, position);
		AppUtils.launchActivity(MainService.this, AppActivity.class, null,
				bundle, true);

	}

	@Override
	public void onClick(View v) {
		String tag = (String) v.getTag();
		// ================================MAIN===============================
		if (getString(R.string.tag_icon).equals(tag)) {
			showView(mFloatView);
		} else if (getString(R.string.tag_cpu).equals(tag)) {
			AppUtils.launchActivity(getApplicationContext(),
					SpecsActivity.class);
			showView(mFloatIcon);
		} else if (getString(R.string.tag_home).equals(tag)) {
			AppUtils.launchHomeApp(getApplicationContext());
			showView(mFloatIcon);
		} else if (getString(R.string.tag_lock).equals(tag)) {
			CONFIG.ADMIN_DEVICE.addDeviceAdmin(getApplicationContext());
			showView(mFloatIcon);
		} else if (getString(R.string.tag_recent).equals(tag)) {
			AppUtils.launchRecentApps();
			showView(mFloatIcon);
		} else if (getString(R.string.tag_app).equals(tag)) {
			AppUtils.launchActivity(getApplicationContext(), AppActivity.class);
			showView(mFloatIcon);
		} else if (getString(R.string.tag_restart).equals(tag)) {
			RootTools.restartAndroid();
		}
		// ================================SUB===============================
		else if (getString(R.string.tag_wifi).equals(tag)) {
			Utils.WIFI.toggleWifi(getApplicationContext());
		} else if (getString(R.string.tag_bluetooth).equalsIgnoreCase(tag)) {
			Utils.Bluetooth.toggleBluetoothEnabled(getApplicationContext());
		} else if (getString(R.string.tag_sound).equalsIgnoreCase(tag)) {
			Utils.switchSoundMode(getApplicationContext());
		} else if (getString(R.string.tag_data).equalsIgnoreCase(tag)) {
			if (!Utils.Mobile.canToggleMobileData(getApplicationContext())) {
				AppUtils.launchWirelessSettings(getApplicationContext());
				showView(mFloatIcon);
			} else {
				Utils.Mobile.toggleMobileData(getApplicationContext());
			}
		} else if (getString(R.string.tag_airplane).equalsIgnoreCase(tag)) {
			Utils.Airplane.toggleAirPlaneMode(getApplicationContext());
			showView(mFloatIcon);
		} else if (getString(R.string.tag_gps).equalsIgnoreCase(tag)) {
			if (!Utils.GPS.canToggleGPS(getApplicationContext())) {
				AppUtils.launchGPSSettings(getApplicationContext());
				showView(mFloatIcon);
			} else {
				Utils.GPS.toggleGPS(getApplicationContext());
			}
		} else if (getString(R.string.tag_light).equalsIgnoreCase(tag)) {
			AppUtils.launchActivity(getApplicationContext(),
					TorchActivity.class);
			showView(mFloatIcon);
		} else if (getString(R.string.tag_mirror).equalsIgnoreCase(tag)) {
			AppUtils.launchActivity(getApplicationContext(),
					MirrorActivity.class);
			showView(mFloatIcon);
		} else if (getString(R.string.tag_camera).equalsIgnoreCase(tag)) {
			AppUtils.launchCameraApp(getApplicationContext());
			showView(mFloatIcon);
		} else if (getString(R.string.tag_rotate).equalsIgnoreCase(tag)) {
			Utils.Rotation.toggleAutoOrientation(getApplicationContext());
		}

	}

	private OnTouchListener mTouchFloatViewListener = new OnTouchListener() {

		private float initialX;

		@Override
		public boolean onTouch(View v, MotionEvent touchevent) {
			switch (touchevent.getAction()) {
			case MotionEvent.ACTION_DOWN:
				initialX = touchevent.getX();
				break;
			case MotionEvent.ACTION_MOVE:
				break;
			case MotionEvent.ACTION_UP:
				float finalX = touchevent.getX();
				if (initialX > finalX) {
					mFloatView.setInAnimation(getApplicationContext(),
							R.anim.in_right);
					mFloatView.setOutAnimation(getApplicationContext(),
							R.anim.out_left);

					if (mFloatView.getDisplayedChild() == 2) {
						mFloatView.setDisplayedChild(0);
						break;
					}

					mFloatView.showNext();
				} else {
					mFloatView.setInAnimation(getApplicationContext(),
							R.anim.in_left);
					mFloatView.setOutAnimation(getApplicationContext(),
							R.anim.out_right);
					if (mFloatView.getDisplayedChild() == 0) {
						mFloatView.setDisplayedChild(2);
						break;
					}

					((ViewFlipper) mFloatView).showPrevious();
				}
				break;
			case MotionEvent.ACTION_OUTSIDE:
				showView(mFloatIcon);
				break;
			}
			return false;
		}
	};
	private OnTouchListener mTouchFloatIconListener = new OnTouchListener() {
		@SuppressWarnings("deprecation")
		@SuppressLint({ "NewApi", "ClickableViewAccessibility" })
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction()) {
			case MotionEvent.ACTION_MOVE:
				int deltaX = (int) (event.getRawX() - mX);
				int deltaY = (int) (event.getRawY() - mY);
				mFloatIconParams.x += deltaX;
				mFloatIconParams.y += deltaY;
				mWindowManager.updateViewLayout(mFloatIcon, mFloatIconParams);
				break;
			case MotionEvent.ACTION_UP:
				int width = 0;
				int height = 0;
				Display display = mWindowManager.getDefaultDisplay();
				if (Build.VERSION.SDK_INT < 13) {
					width = display.getWidth();
					height = display.getHeight();
				} else {
					Point point = new Point();
					mWindowManager.getDefaultDisplay().getSize(point);
					width = point.x;
					height = point.y;
				}

				if (mX == width || mY == height) {
					break;
				}
				float deltaW = width - mX;
				float deltaH = height - mY;
				int newX = 0;
				int newY = 0;
				if (mX < deltaW) {
					if (mX < mY && mX < deltaH) {
						newX = getNewPosition(mFloatIconParams.x, width);
					} else {
						newY = getNewPosition(mFloatIconParams.y, height);
					}
				} else {
					if (deltaW < mY && deltaW < deltaH) {
						newX = getNewPosition(mFloatIconParams.x, width);
					} else {
						newY = getNewPosition(mFloatIconParams.y, height);
					}
				}
				animationToNewPosition(newX, newY);
			default:
				break;
			}
			mX = event.getRawX();
			mY = event.getRawY();
			return false;
		}
	};

	private void animationToNewPosition(final int newX, final int newY) {
		if (newX != 0) {
			int curX = mFloatIconParams.x;
			final int deltaX = (newX - curX) / 20;
			new CountDownTimer(200, 10) {

				@Override
				public void onTick(long millisUntilFinished) {
					try {
						mFloatIconParams.x += deltaX;
						mWindowManager.updateViewLayout(mFloatIcon,
								mFloatIconParams);
					} catch (Exception e) {
						cancel();
					}

				}

				@Override
				public void onFinish() {
					try {
						mFloatIconParams.x = newX;
						mWindowManager.updateViewLayout(mFloatIcon,
								mFloatIconParams);
					} catch (Exception e) {
						cancel();
					}
				}

			}.start();
			return;
		}

		if (newY != 0) {
			int curY = mFloatIconParams.y;
			final int deltaY = (newY - curY) / 20;
			new CountDownTimer(200, 10) {

				@Override
				public void onTick(long millisUntilFinished) {
					try {
						mFloatIconParams.y += deltaY;
						mWindowManager.updateViewLayout(mFloatIcon,
								mFloatIconParams);
					} catch (Exception e) {
						cancel();
					}

				}

				@Override
				public void onFinish() {
					try {
						mFloatIconParams.y = newY;
						mWindowManager.updateViewLayout(mFloatIcon,
								mFloatIconParams);
					} catch (Exception e) {
						cancel();
					}

				}
			}.start();

		}

	}

	private int getNewPosition(int curDimension, int maxDimension) {
		if (curDimension > 0) {
			return maxDimension / 2;
		} else {
			return -maxDimension / 2;
		}
	}

	private void showView(View view) {
		View hidenView = view == mFloatView ? mFloatIcon : mFloatView;
		hidenView.setVisibility(View.GONE);
		view.setVisibility(View.VISIBLE);

	}

}
